package com.glsc.ngateway.filetransfer.controller;


import cn.hutool.core.util.StrUtil;
import com.glsc.ngateway.common.api.common.utils.JsonUtil;
import com.glsc.ngateway.common.api.filetransfer.dto.CommonFileDto;
import com.glsc.ngateway.common.api.filetransfer.dto.CommonFileUploadDto;
import com.glsc.ngateway.common.api.filetransfer.dto.FileType;
import com.glsc.ngateway.common.api.filetransfer.dto.ReportShowResponse;
import com.glsc.ngateway.common.api.filetransfer.enums.CommonTypeEnum;
import com.glsc.ngateway.common.api.filetransfer.resp.FileTransferResponse;
import com.glsc.ngateway.common.base.domain.mysql.fileTransfer.CommonFile;
import com.glsc.ngateway.filetransfer.service.CommonFileService;
import com.glsc.ngateway.filetransfer.util.FileUtil;
import com.glsc.ngateway.filetransfer.util.TokenUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.URLEncoder;
import java.util.Objects;

@RestController
@Api(value = "通用文件服务", tags = {"通用文件服务"})
@RequestMapping("/api/commonFile")
@Slf4j
public class CommonFileController {

    @Resource
    private CommonFileService commonFileService;

    @Value("${commonFile.downloadUrl}")
    String downloadUrl;

    @Resource
    TokenUtil tokenUtil;

    /**
     * 文件上传
     *
     * @param
     * @return
     * @throws IOException
     */
    @PostMapping("/uploadFile")
    @ApiOperation(value = "文件上传", notes = "上传产品文件，不大于100M")
    public FileTransferResponse<CommonFileDto> uploadFile(@RequestPart("file") MultipartFile file,
                                                          @ApiParam(value = "系统编码-必传") @RequestParam(required = true) String systemCode,
                                                          @ApiParam(value = "文件id-更新文件时必传，不传则表示新增") @RequestParam(required = false) String fileId,
                                                          @ApiParam(value = "创建者oa账号") @RequestParam(required = false) String oaAccount,
                                                          @ApiParam(value = "创建者姓名") @RequestParam(required = false) String creatorName,
                                                          @ApiParam(value = "文件描述") @RequestParam(required = false) String fileDesc) throws IOException {
        CommonFileDto commonFileDto = commonFileService.uploadFile(file, systemCode, fileId, oaAccount, creatorName, fileDesc);
        return FileTransferResponse.success(commonFileDto);
    }

    /**
     * 下载
     *
     * @param fileId
     * @return
     * @throws IOException
     */
    @GetMapping("/download")
    @ApiOperation(value = "根据fileId下载文件", notes = "根据fileId下载文件")
    public FileTransferResponse<byte[]> download(@ApiParam(required = true, value = "fileId") @RequestParam String fileId
            , @ApiParam(required = true, value = "systemCode") @RequestParam String systemCode) throws IOException {

        Assert.isTrue(StringUtils.isNoneBlank("fileId"), "查询文件的fileId不可为空");
        Assert.isTrue(StringUtils.isNoneBlank("systemCode"), "查询文件的systemCode不可为空");
        Assert.isTrue(Objects.nonNull(CommonTypeEnum.findByCode(systemCode)), "查询文件的systemCode错误");

        CommonFile commonFile = commonFileService.findByFileId(fileId, systemCode);
        Assert.isTrue(Objects.nonNull(commonFile), "文件不存在");

        byte[] bytes = FileUtil.readByteFromFilePath(commonFile.getFilePath());

        return FileTransferResponse.success(bytes);
    }


    /**
     * 通用文件预览接口
     *
     * @param fileId
     * @return
     */
    @RequestMapping(method = RequestMethod.GET, value = "/showDoc")
    public FileTransferResponse<ReportShowResponse> show(@ApiParam(required = true, value = "文件ID") @RequestParam String fileId) {

        CommonFile commonFileDb = commonFileService.findByFileId(fileId, null);

        FileTransferResponse<ReportShowResponse> ret = null;
        try {
            String title = commonFileDb.getFileName();
            String url = downloadUrl + fileId;
            String token = tokenUtil.generateToken(JsonUtil.Obj2Str(new ReportShowResponse(title, url, FileType.valueOf(title.substring(title.lastIndexOf(".") + 1)))));

            ReportShowResponse resdata = new ReportShowResponse(title, url, token, FileType.valueOf(title.substring(title.lastIndexOf(".") + 1)));
            ret = FileTransferResponse.success(resdata);

            ret.setFileId(title);
        } catch (Exception e) {
            ret = FileTransferResponse.failError(e.getMessage(), e);
        }

        return ret;
    }

    /**
     * 文件预览专用下载接口-无鉴权,前端页面不要使用[后续要优化]
     *
     * @param fileId
     * @return
     * @throws IOException
     */
    @GetMapping("/showDoc/download")
    @ApiOperation(value = "文件预览专用下载接口", notes = "文件预览专用下载接口")
    public ResponseEntity<byte[]> getContentById4ShowDoc(@ApiParam(required = true, value = "文件id") @RequestParam String fileId) throws IOException {
        Assert.isTrue(StringUtils.isNotBlank(fileId), "查询文件ID不合法");

        CommonFile commonFileDb = commonFileService.findByFileId(fileId, null);

        if (null == commonFileDb || StrUtil.isEmpty(commonFileDb.getFileName())) {
            return null;
        }

        HttpHeaders headers = new HttpHeaders();
        ResponseEntity<byte[]> entity = null;
        InputStream in = null;
        in = new FileInputStream(new File(commonFileDb.getFilePath()));
        byte[] bytes = new byte[in.available()];
        String imageName = commonFileDb.getFileName();
        //处理IE下载文件的中文名称乱码的问题
        ServletRequestAttributes attrs = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = ((ServletRequestAttributes) attrs).getRequest();
        String header = request.getHeader("User-Agent").toUpperCase();
        if (header.contains("MSIE") || header.contains("TRIDENT") || header.contains("EDGE")) {
            imageName = URLEncoder.encode(imageName, "utf-8");
            imageName = imageName.replace("+", "%20"); //IE下载文件名空格变+号问题
        } else {
            imageName = new String(imageName.getBytes(), "iso-8859-1");
        }
        in.read(bytes);
        headers.add("Content-Disposition", "attachment;filename=" + imageName);
        entity = new ResponseEntity<byte[]>(bytes, headers, HttpStatus.OK);
        return entity;
    }

    /**
     * 根据文件id获取file对象
     *
     * @param fileId
     * @return
     * @throws Exception
     */
    @RequestMapping(method = RequestMethod.POST, value = "/findFileByFileId")
    public File findFileByFileId(@ApiParam(required = true, value = "文件id") @RequestParam String fileId) throws Exception {
        Assert.isTrue(StringUtils.isNotBlank(fileId), "查询文件ID不合法");
        CommonFile commonFile = commonFileService.findByFileId(fileId, null);
        if (null == commonFile || StrUtil.isEmpty(commonFile.getFileName())) {
            return null;
        }
        File file = new File(commonFile.getFilePath());
        return file;
    }


}
